import {
  CanActivate,
  ExecutionContext,
  Injectable,
  Logger,
} from '@nestjs/common';
import { UserIdentity } from '@/common/auth/dto/user-identity.dto';
import { UserNotFoundException } from '@/exceptions';
import { ConfigService } from '@/common/config/config.service';
import { UserRole } from '@/enum';

/**
 * Check if `request.params.id === user.id` or user has admin role
 */
@Injectable()
export class SelfOnlyGuard implements CanActivate {
  constructor(private readonly config: ConfigService) {}

  canActivate(context: ExecutionContext): boolean {
    if (!this.config.isAuthEnabled) {
      Logger.warn(
        `Authorization has been disabled due to environment setting.
      DO NOT TURN OFF AUTHORIZATION IN PRODUCTION UNLESS YOU KNOW EXACTLY WHAT YOU'RE DOING!`,
        'SelfOnlyGuard',
      );
      return true;
    }
    const request = context.switchToHttp().getRequest();
    const user = request.user as UserIdentity;
    if (!user) {
      throw new UserNotFoundException(
        'Authorized user is required by SelfOnlyGuard.',
      );
    }
    return (
      user.id === Number(request.params.id) ||
      user.roles.findIndex(role => role === UserRole.ADMIN) !== -1
    );
  }
}
